using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CxRomos.Core.Domain.Entities;
using StructureMap;

namespace CxRomos.Core.Services.Implementation {
    [Pluggable("Default")]
    public class Navigation : INavigation {
        private readonly IUserSession _usersSession;
        private readonly IRedirector _redirector;
        private readonly Account _account;

        public Navigation() {
            _usersSession = ObjectFactory.GetInstance<IUserSession>();
            _redirector = ObjectFactory.GetInstance<IRedirector>();
            _account = _usersSession.CurrentUser;
        }


        public List<SiteMapNode> AllNodes() {
            var nodes = new List<SiteMapNode> {SiteMap.RootNode};
            nodes.AddRange(SiteMap.RootNode.ChildNodes.Cast<SiteMapNode>());
            
            return nodes;
        }

        public List<SiteMapNode> PrimaryNodes() {
            var primaryNodes = AllNodes().Where(node => node["topnav"] != null && CheckAccessForNode(node)).ToList();
            return primaryNodes;
        }

        public List<SiteMapNode> FooterNodes() {
            var footerNodes = AllNodes().Where(node => node["footernav"] != null && CheckAccessForNode(node)).ToList();
            return footerNodes;
        }

        private bool CheckAccessForNode(SiteMapNode node) {
            if (!node.Roles.Contains("PUBLIC")) {
                if (_account != null && _account.Permissions != null && _account.Permissions.Count > 0) {
                    return node.Roles.Cast<string>().All(role => _account.HasPermission(role));
                }
                return false;
            }

            return true;
        }

        public void CheckAccessForCurrentNode() {
            var result = CheckAccessForNode(CurrentNode);
            if (result)
                return;
            
            _redirector.GoToAccountAccessDenied();
        }

        public SiteMapNode RootNode {
            get { return SiteMap.RootNode; }
        }

        public SiteMapNode CurrentNode {
            get { return SiteMap.CurrentNode; }
        }
    }
}